LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
USE ieee.std_logic_unsigned.all;

ENTITY ScreenSender IS
	PORT
	(
		Clk : IN std_logic;
		Reset : IN std_logic;
		Enable : IN std_logic;
		Txd_SendData : OUT std_logic_vector(7 DOWNTO 0);
		SendEnable : OUT std_logic;
		SendBusy : IN std_logic;
		--- Memory Port
		SecoAddr : OUT std_logic_vector(9 DOWNTO 0);
		SecoReadData : IN std_logic_vector(15 DOWNTO 0)
	);
END ENTITY;

ARCHITECTURE rtl OF ScreenSender IS
	TYPE State_Type IS (Idle, Init, Send_Read_Pre ,Send_Read, Send_Read_Wait, Send_Read_Finish, Send_Wait0, Send_Wait1, Send_Wait2, Send_Wait3);
	SIGNAL state : State_Type;
	SIGNAL DataCache : std_logic_vector(15 DOWNTO 0);
	SIGNAL PosX, PosY : std_logic_vector(4 DOWNTO 0);
	SIGNAL sCounter : std_logic_vector(2 DOWNTO 0);
	SIGNAL Sending : std_logic;
	SIGNAL SendingCounter : std_logic_vector(3 downto 0);
BEGIN
	
	cMainCtl : PROCESS(Clk, Reset)
	BEGIN
		IF Reset = '0' THEN
			state <= Idle;
			PosX <= "00000";
			PosY <= "00001";
		ELSIF rising_edge(Clk) THEN
			IF(Sending = '1')THEN
				SendEnable <= '1';
				IF(SendingCounter>0)THEN
					SendingCounter <= SendingCounter - 1;
				ELSE
					Sending <= '0';
					SendingCounter <= "1111";
				END IF;
			ELSE
			SendEnable <= '0';
			CASE state IS

				WHEN Idle =>
					IF Enable = '1' THEN
						state <= Init;
					ELSE
						state <= Idle;
					END IF;
				WHEN Init =>
					IF SendBusy = '0' THEN
						PosX <= "00000";
						PosY <= "00001";
						Txd_SendData <= "10000000";
						Sending <= '1';
						state <= Send_Read_Pre;
					ELSE
						state <= Init;
					END IF;
--				WHEN Send_Wait0 =>
--					IF SendBusy = '0' THEN
--							-- Cache Sendied data
--							TxD_SendData <= "01" & DataCache(5 downto 0);
--							Sending <= '1';
--							state <= Send_Wait1;
--					ELSE
--						state <= Send_Wait0;
--					END IF;
--				WHEN Send_Wait1 =>
--					IF SendBusy = '0' THEN
--							-- Cache Sendied data
--							Txd_SendData <= "01" & DataCache(11 downto 6);
--							Sending <= '1';
--							state <= Send_Wait2;
--					ELSE
--						state <= Send_Wait1;
--					END IF;
--				WHEN Send_Wait2 =>
--					IF SendBusy = '0' THEN
--							-- Cache Sendied data
--							Txd_SendData <= "01" & DataCache(17 downto 12);
--							Sending <= '1';
--							state <= Send_Wait3;
--					ELSE
--						state <= Send_Wait2;
--					END IF;
				WHEN Send_Wait3 =>
					IF SendBusy = '0' THEN
							-- Cache Sendied data
							Txd_SendData <= "01" & "00" & DataCache(3 downto 0);
							Sending <= '1';
							-- Update Position
							IF PosX = 25 THEN
								PosX <= "00001";
								IF PosY = 18 THEN
									state <= Init;
								ELSE
									PosY <= PosY +1;
									state <= Send_Read_Pre;
								END IF;
							ELSE
								PosX <= PosX +1;
								state <= Send_Read_Pre;
							END IF;
					ELSE
						state <= Send_Wait3;
					END IF;
				WHEN Send_Read_Pre =>
					SecoAddr <= PosY & PosX;
					state <= Send_Read;
				WHEN Send_Read =>
					sCounter <= "000";
					state <= Send_Read_Wait;
				WHEN Send_Read_Wait =>
					IF(sCounter = 1)THEN
						state <= Send_Read_Finish;
					ELSE
						sCounter <= sCounter + 1;
						state <= Send_Read_Wait;
					END IF;
				WHEN Send_Read_Finish =>
					DataCache <= SecoReadData;
					state <= Send_Wait3;
				WHEN OTHERS =>
					state <= Idle;
			END CASE;
			END IF;
		END IF;
	END PROCESS;
END rtl;